// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.core.skinnedmodel.animation;

import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Quaternion;
import org.lwjgl.util.vector.Vector3f;
import zombie.core.skinnedmodel.HelperFunctions;
import zombie.util.Pool;
import zombie.util.PooledObject;

public class BoneTransform extends PooledObject {
    private boolean m_matrixValid = true;
    private final Matrix4f m_matrix = new Matrix4f();
    private final HelperFunctions.TransformResult_QPS m_transformResult = new HelperFunctions.TransformResult_QPS(this.m_matrix);
    private boolean m_prsValid = true;
    private final Vector3f m_pos = new Vector3f();
    private final Quaternion m_rot = new Quaternion();
    private final Vector3f m_scale = new Vector3f();
    private static final Pool<BoneTransform> s_pool = new Pool<>(BoneTransform::new);

    protected BoneTransform() {
        this.setIdentity();
    }

    public void setIdentity() {
        this.m_matrixValid = true;
        this.m_matrix.setIdentity();
        this.m_prsValid = true;
        this.m_pos.set(0.0F, 0.0F, 0.0F);
        this.m_rot.setIdentity();
        this.m_scale.set(1.0F, 1.0F, 1.0F);
    }

    public void set(BoneTransform rhs) {
        this.m_matrixValid = rhs.m_matrixValid;
        this.m_prsValid = rhs.m_prsValid;
        this.m_pos.set(rhs.m_pos);
        this.m_rot.set(rhs.m_rot);
        this.m_scale.set(rhs.m_scale);
        this.m_matrix.load(rhs.m_matrix);
    }

    public void set(Vector3f vector3f1, Quaternion quaternion, Vector3f vector3f0) {
        if (this.m_matrixValid || !this.m_prsValid || !this.m_pos.equals(vector3f1) || !this.m_rot.equals(quaternion) || !this.m_scale.equals(vector3f0)) {
            this.m_matrixValid = false;
            this.m_prsValid = true;
            this.m_pos.set(vector3f1);
            this.m_rot.set(quaternion);
            this.m_scale.set(vector3f0);
        }
    }

    public void set(Matrix4f matrix4f) {
        this.m_matrixValid = true;
        this.m_matrix.load(matrix4f);
        this.m_prsValid = false;
    }

    public void mul(Matrix4f matrix4f0, Matrix4f matrix4f1) {
        this.m_matrixValid = true;
        this.m_prsValid = false;
        Matrix4f.mul(matrix4f0, matrix4f1, this.m_matrix);
    }

    public void getMatrix(Matrix4f matrix4f) {
        matrix4f.load(this.getValidMatrix_Internal());
    }

    public void getPRS(Vector3f vector3f0, Quaternion quaternion, Vector3f vector3f1) {
        this.validatePRS();
        vector3f0.set(this.m_pos);
        quaternion.set(this.m_rot);
        vector3f1.set(this.m_scale);
    }

    public void getPosition(Vector3f vector3f) {
        this.validatePRS();
        vector3f.set(this.m_pos);
    }

    private Matrix4f getValidMatrix_Internal() {
        this.validateMatrix();
        return this.m_matrix;
    }

    private void validateMatrix() {
        if (!this.m_matrixValid) {
            this.validateInternal();
            this.m_matrixValid = true;
            HelperFunctions.CreateFromQuaternionPositionScale(this.m_pos, this.m_rot, this.m_scale, this.m_transformResult);
        }
    }

    protected void validatePRS() {
        if (!this.m_prsValid) {
            this.validateInternal();
            this.m_prsValid = true;
            HelperFunctions.getPosition(this.m_matrix, this.m_pos);
            HelperFunctions.getRotation(this.m_matrix, this.m_rot);
            this.m_scale.set(1.0F, 1.0F, 1.0F);
        }
    }

    protected void validateInternal() {
        if (!this.m_prsValid && !this.m_matrixValid) {
            throw new RuntimeException("Neither the matrix nor the PosRotScale values in this object are listed as valid.");
        }
    }

    public static void mul(BoneTransform boneTransform, Matrix4f matrix4f0, Matrix4f matrix4f1) {
        Matrix4f.mul(boneTransform.getValidMatrix_Internal(), matrix4f0, matrix4f1);
    }

    public static BoneTransform alloc() {
        return s_pool.alloc();
    }
}
